use std::collections::HashMap;
use std::path::Path;
use std::time::SystemTime;
use axum::extract::{Multipart, State};
use axum::Json;
use axum::response::IntoResponse;
use chrono::{DateTime, Utc};
use http::StatusCode;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use sha2::{Sha256,Digest};
use tokio::fs;
use tokio::io::{AsyncReadExt, AsyncWriteExt, BufReader, BufWriter};
use crate::config::{address, final_address, json_IdMd5, json_file};
use serde_json::{from_slice, to_vec_pretty};
use tokio::fs::File;
use crate::models::AppState::AppState;
use crate::models::FileEntry::{FileEntry, FileInfo, IdMd5};
use crate::models::UploadResponse::UploadResponse;
type FileDatabase = HashMap<String, FileEntry>;
pub async fn upload_file(State(state):State<AppState>, mut multipart: Multipart) -> impl IntoResponse {
    //可以取请求的header
    let mut original_file_name = String::new();
    let mut file_type = "unknown".to_string();
    let mut file_name = original_file_name.clone();
    let mut modify_time = String::new();
    let mut file_size = 0;
    let mut hasher = Sha256::new();
    let mut buffer = Vec::new();
    while let Ok(Some(mut field)) = multipart.next_field().await{
        if let Some(name) = field.name() {
            match name {
                "file" => {
                    println!("{:?}",field.name());
                    original_file_name = field.file_name().map(|s| s.to_string()).unwrap_or_else(|| Uuid::new_v4().to_string());
                    file_name = original_file_name.clone();
                    file_type = field.content_type().map(|s| s.to_string()).unwrap_or_else(|| "unknown".to_string());
                    println!("第46行");
                    while let Ok(Some(chunk)) = field.chunk().await{
                        hasher.update(&chunk);
                        buffer.extend_from_slice(&chunk);
                    };
                    file_size = buffer.len() as u64;
                    let now_chrono: DateTime<Utc> = SystemTime::now().into();
                    modify_time = now_chrono.format("%Y-%m-%d %H:%M:%S").to_string();
                },
                _ => {
                    println!("第71行");
                }
            }
        }
    }
    // 继续处理文件信息
    println!("Original File Name: {}", original_file_name);
    println!("File Type: {}", file_type);
    println!("File Name: {}", file_name);
    println!("Modify Time: {}", modify_time);
    println!("File Size: {}", file_size);
    // 计算文件的 MD5 哈希值
    let result = hasher.finalize();
    let md5 = result.iter().map(|b| format!("{:02x}", b)).collect::<String>(); // 手动格式化为十六进制字符串
    println!("MD5: {}", md5);
    // 构建文件名
    let file_name_with_md5 = format!("{}_{}", file_name, md5);//不能修改md5名字
    let file_path = format!("{}/{}", address, file_name_with_md5);
    let url = format!("{}{}", final_address, file_name_with_md5);
    // 创建文件夹
    fs::create_dir_all(Path::new(address)).await.expect("创建文件夹失败");
    // 写入文件
    let mut file = fs::File::create(&file_path).await.expect("创建文件失败");
    file.write_all(&buffer).await.expect("写入文件失败");
    // 构建文件信息
    let file_info = FileInfo {
        name: file_name.clone(),
        modify_time,
        file_type,
        file_size,
    };
    let mut file_databases = state.file_database.clone();
    let mut file = file_databases.lock().await;
    //应该将这个读取json执行在服务器启动时作为公共参数。
    println!("第109{:?}",file);
    if file.data.contains_key(&md5){
        if(file.data.get_mut(&md5).unwrap().info.contains_key(&file_name)){
            return (StatusCode::OK,Json(UploadResponse{url}))
        }else{
            file.data.get_mut(&md5).unwrap().info.insert(file_name.clone(),file_info);
        }
    }else{
        let new_id :u64 = file.data.len() as u64 + 1;
        let file_entry =  FileEntry{
            id:new_id,
            info: HashMap::from([(file_name.clone(), file_info)]),
        };
        file.data.insert(md5.clone(),file_entry);
        file.id_md5.insert(new_id.clone(),md5.clone());
    };
    // let json_content = serde_json::to_string_pretty(&file.id_md5).expect("序列化 JSON 失败");
    // fs::write(json_IdMd5, json_content).await.expect("写入 JSON 文件失败");
    // let json_contents = serde_json::to_string_pretty(&file.data).expect("序列化 JSON 失败");
    // fs::write(json_file, json_contents).await.expect("写入 JSON 文件失败");
    AppState::write_file_data_to_json_idmd5(&file.id_md5).await;
    AppState::write_file_data_to_json_file(&file.data).await;
    (StatusCode::OK, Json(UploadResponse { url }))
}
